package com.yufei.utils;


import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.xml.namespace.NamespaceContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;




public class XPathUtil {
public static List<String> getNodeListTextByXPath(InputStream source,String xpath) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{
	String value=null;
	 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	    domFactory.setNamespaceAware(false); // never forget this!


	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(source);

	    XPathFactory factory = XPathFactory.newInstance();
	    XPath path = factory.newXPath();
	    XPathExpression expr 
	     = path.compile(xpath);
	   
	    NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
	  List<String> strs=new ArrayList();
	  for(int i=0;i<nodeList.getLength();i++){
		  strs.add(nodeList.item(i).getTextContent());
	  }
	return strs;
}
/**
 * @param source
 * @param xpath
 * @return 
 * @throws XPathExpressionException
 * @throws ParserConfigurationException
 * @throws SAXException
 * @throws IOException
 */
public static List<String> getNodeListTextByXPath(String source,String xpath) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{
	String value=null;
	 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	    domFactory.setNamespaceAware(false); // never forget this!

	    InputSource inputSource=new InputSource(new StringReader(source));
	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(inputSource);

	    XPathFactory factory = XPathFactory.newInstance();
	    XPath path = factory.newXPath();
	    XPathExpression expr 
	     = path.compile(xpath);
	   
	    NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
	  List<String> strs=new ArrayList();
	  for(int i=0;i<nodeList.getLength();i++){
		  strs.add(nodeList.item(i).getTextContent());
	  }
	return strs;
}
public static String getNodeTextByXPath(InputStream source,String xpath) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{
	String value=null;
	 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	    domFactory.setNamespaceAware(false); // never forget this!


	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(source);

	    XPathFactory factory = XPathFactory.newInstance();
	    XPath path = factory.newXPath();
	    XPathExpression expr 
	     = path.compile(xpath);
	   
	    Node node = (Node) expr.evaluate(doc, XPathConstants.NODE);
	      if(node==null){
	    	  return null;
	      }
		  value=node.getTextContent();
	  
	return value;
}
public static NodeList getNodeListtByXPath(InputStream source,String xpath) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{
	String value=null;
	 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	    domFactory.setNamespaceAware(false); // never forget this!


	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(source);

	    XPathFactory factory = XPathFactory.newInstance();
	    XPath path = factory.newXPath();
	    XPathExpression expr 
	     = path.compile(xpath);
	   
	    NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
	
	return nodeList;
}
public static NodeList getNodeListtByXPath(String source,String xpath) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{
	String value=null;
	 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	    domFactory.setNamespaceAware(false); // never forget this!
	    InputSource inputSource=new InputSource(new StringReader(source));

	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(inputSource);

	    XPathFactory factory = XPathFactory.newInstance();
	    XPath path = factory.newXPath();
	    XPathExpression expr 
	     = path.compile(xpath);
	   
	    NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
	
	return nodeList;
}
public static NodeList getNodeListtByXPath(String source,String xpath,NamespaceContext namespaceContext) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{
	String value=null;
	 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	    domFactory.setNamespaceAware(true); // never forget this!
	    InputSource inputSource=new InputSource(new StringReader(source));

	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(inputSource);

	    XPathFactory factory = XPathFactory.newInstance();
	    XPath path = factory.newXPath();
	    path.setNamespaceContext(namespaceContext)
	    ;
	    XPathExpression expr 
	     = path.compile(xpath);
	   
	    NodeList nodeList = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
	
	return nodeList;
}
/**
 * @param source
 * @param xpath
 * @return
 * @throws XPathExpressionException
 * @throws ParserConfigurationException
 * @throws SAXException
 * @throws IOException
 * 解析字符串
 */
public static String getNodeTextByXPath(String source,String xpath) throws XPathExpressionException, ParserConfigurationException, SAXException, IOException{
	String value=null;
	 DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
	    domFactory.setNamespaceAware(false); // never forget this!

	    InputSource inputSource=new InputSource(new StringReader(source));
	    DocumentBuilder builder = domFactory.newDocumentBuilder();
	    Document doc = builder.parse(inputSource);

	    XPathFactory factory = XPathFactory.newInstance();
	    XPath path = factory.newXPath();
	    XPathExpression expr 
	     = path.compile(xpath);
	   
	    Node node = (Node) expr.evaluate(doc, XPathConstants.NODE);
	 
	  if(node==null){
		  return null;
	  }
	return node.getTextContent();
}



public static void main(String[] args) throws IOException, XPathExpressionException, ParserConfigurationException, SAXException{
	

	/*String requestAmazonUrl=ShopDataUrlGenerator.getAmazonItemLookupUrl("B007VJXUIC,B003P8PHGQ,B123002347GU6GA0,B00ANIQLX4,B009341LBG,B008O2NTMC,B005BWRXHU,B005F2I1QS,B00AFPQJEG");
	
	ProxyServer proxyServer=null;
	String xml=CommonUtil.getHtmlContent(proxyServer, false, requestAmazonUrl);
     System.out.print(xml);

    //
	System.out.print(XPathUtil.getNodeTextByXPath(xml,AmazonShopDataConsumer.priceXPath));*/
/*	List<String> asins=XPathUtil.getNodeListTextByXPath(Thread.currentThread().getContextClassLoader().getResourceAsStream("amazoneResponse.xml"), "//Item/ASIN");
  
   List<String> prices=XPathUtil.getNodeListTextByXPath(Thread.currentThread().getContextClassLoader().getResourceAsStream("amazoneResponse.xml"), "//Item/OfferSummary/LowestNewPrice/FormattedPrice");
   for(String asin:asins){
	   System.out.print(asin+"\n");
   }
   for(String price:prices){
	   System.out.print(price+"\n");
   }
   NodeList nodeList=XPathUtil.getNodeListtByXPath(Thread.currentThread().getContextClassLoader().getResourceAsStream("amazoneResponse.xml"), "//Item");
   System.out.print(nodeList.toString());
   Node itemNode=null;
   for(int i=0;i<nodeList.getLength();i++){
	   itemNode=nodeList.item(i);
	   System.out.print(XPathUtil.getValueOfNode(itemNode, "ASIN")+";"+XPathUtil.getValueOfNode(itemNode, "FormattedPrice")+""+"\n");
	   
   }*/
	   NodeList nodeList=XPathUtil.getNodeListtByXPath(Thread.currentThread().getContextClassLoader().getResourceAsStream("amazoneResponse.xml"), "//Item");
       Node node=nodeList.item(0);
	Node aNode=XPathUtil.getNode(node, "Height");
	System.out.print(XPathUtil.getAttributeValue(aNode, "Units"));
	//System.out.print(XPathUtil.getValueOfNode(aNode, "URL"));
}
public static String getAttributeValue(Node node,String attrName){
	String attrValue=null;
	NamedNodeMap attrs=node.getAttributes();
	  for(int i = 0 ; i<attrs.getLength() ; i++) {
	        Attr attribute = (Attr)attrs.item(i);     
	      if(attribute.getName().equals(attrName)){
	    	  attrValue=attribute.getValue();
	    	  break;
	      }
	      }
	return attrValue;
	
}
/**
 * @param node
 * @param nodeName
 * @return null 如果找不到需要的节点信息
 */
public static String getValueOfNode(Node node,String nodeName){
	String value=null;
	if(node==null){
		throw new IllegalArgumentException();
	}
	if(node.getNodeName().equals(nodeName)){
		return node.getTextContent();
	}
	NodeList childNodes=node.getChildNodes();
	for(int i=0;i<childNodes.getLength();i++){
		if(childNodes.item(i).getNodeName().equals(nodeName)){
			
			return childNodes.item(i).getTextContent();
		}
		else{
			
		value=getValueOfNode(childNodes.item(i), nodeName);
		if(value!=null){
			break;
			
		}
		}
	}
	
	
	
	
	return value;
	
}
/**
 * @param pNode：父节点
 * @param nodeName：子节点名称
 * @return
 * 获取某个父节点的子节点
 */
public static Node getNode(Node pNode,String nodeName){
	Node node=null;
	if(pNode==null){
		throw new IllegalArgumentException();
	}
	if(pNode.getNodeName().equals(nodeName)){
		return null;
	}
	NodeList childNodes=pNode.getChildNodes();
	for(int i=0;i<childNodes.getLength();i++){
		if(childNodes.item(i).getNodeName().equals(nodeName)){
			
			return childNodes.item(i);
		}
		else{
			node=getNode(childNodes.item(i), nodeName);
		if(node!=null){
			break;
			
		}
		}
	}
	
	
	
	
	return node;
	
}
}
